#include <iostream>
#include <sw/redis++/redis.h>

namespace ken_im
{
class RedisClientFactory
{
  public:
    static std::shared_ptr<sw::redis::Redis>
    create( const std::string &host, int port, int db, bool keep_alive )
    {
        sw::redis::ConnectionOptions opts;
        opts.host = host;
        opts.port = port;
        opts.db = db;
        opts.keep_alive = keep_alive;
        auto res = std::make_shared<sw::redis::Redis>( opts );
        return res;
    }
};

/**
 * Session 类通过
 * ssid来唯一标识和操作用户的会话信息，从而实现用户会话的管理。ssid
 * 的存在使得每个用户会话都可以独立地存储和检索，提高了系统的灵活性和安全性。
 */
// Session 类用于管理 Redis 会话，包括添加、删除和获取会话信息。
class Session
{
  public:
    using ptr = std::shared_ptr<Session>;
    Session( const std::shared_ptr<sw::redis::Redis> &redis_client )
        : _redis_client( redis_client )
    {
    }
    // 将用户会话 ID（ssid）和用户 ID（uid）关联存储到 Redis 中。
    void append( const std::string &ssid, const std::string &uid )
    {
        _redis_client->set( ssid, uid );
    }
    // 删除指定会话 ID 的会话信息。
    void remove( const std::string &ssid )
    {
        _redis_client->del( ssid );
    }
    // 根据会话 ID 获取对应的用户 ID。
    sw::redis::OptionalString uid( const std::string &ssid )
    {
        return _redis_client->get( ssid );
    }

  private:
    std::shared_ptr<sw::redis::Redis> _redis_client;
};

// 通过 Redis 客户端来操作 Redis 数据库，提供了添加、删除和检查用户状态的功能。
class Status
{
  public:
    using ptr = std::shared_ptr<Status>;
    Status( const std::shared_ptr<sw::redis::Redis> &redis_client )
        : _redis_client( redis_client )
    {
    }
    // 将用户 ID 存储到 Redis 中，表示用户在线。
    void append( const std::string &uid )
    {
        _redis_client->set( uid, "" );
    }
    // 从 Redis 中删除用户 ID，表示用户离线。
    void remove( const std::string &uid )
    {
        _redis_client->del( uid );
    }
    // 检查用户是否在线。
    bool exists( const std::string &uid )
    {
        auto res = _redis_client->get( uid );
        if ( res )
            return true;
        return false;
    }

  private:
    std::shared_ptr<sw::redis::Redis> _redis_client;
};

// 用于与 Redis 数据库进行交互，提供对代码字符串的存储和检索功能
class Codes
{
  public:
    using ptr = std::shared_ptr<Codes>;
    Codes( const std::shared_ptr<sw::redis::Redis> &redis_client )
        : _redis_client( redis_client )
    {
    }
    // 将验证码 ID（cid）和验证码（code）存储到 Redis 中，并设置过期时间（默认 5
    // 分钟）。
    void append( const std::string &cid, const std::string &code,
                 const std::chrono::milliseconds &t =
                     std::chrono::milliseconds( 300000 ) )
    {
        _redis_client->set( cid, code, t );
    }
    // 删除指定验证码 ID 的验证码信息。
    void remove( const std::string &cid )
    {
        _redis_client->del( cid );
    }
    // 根据验证码 ID 获取对应的验证码。
    sw::redis::OptionalString code( const std::string &cid )
    {
        return _redis_client->get( cid );
    }

  private:
    std::shared_ptr<sw::redis::Redis> _redis_client;
};
} // namespace ken_im